#ifndef _NET_H_
#define _NET_H_

#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define IPACCESS_GRANT_LEN	256

/**
 * @brief	judge if fd is socket fd
 */
int net_issocket(int fd);

/**
 * @brief	check if fd is correct
 */
int net_iserror(int fd);

/**
 * @brief	get host byte order
 */
int net_gethostbyteorder();

/**
 * @brief	get socket flag
 */
int net_getsockflag(int fd);

/**
 * @breif	close fd rightnow
 */
void net_close_nodelay(int fd);

/****************************************************************
 * socket wrap function
 ****************************************************************/

/**
 * @brief	connect with timeout ms
 */
int net_connect_ms(int sockfd, const struct sockaddr *s, socklen_t socklen, int msec, int isclose);

/**
 * @brief	connect with timeout
 */
int net_connect_tv(int sockfd, const struct sockaddr *s, socklen_t socklen, struct timeval *tv, int isclose);

/**
 * @brief	set tcp connect wrap function
 */
int net_tcpconnect(const char *ip, uint16_t port, int sec);

/**
 * @brief	set tcp listen wrap function
 */
int net_tcplisten(const char *ip, uint16_t port, int backlog);

/**
 * @brief	set udp listen wrap function
 */
int net_udplisten(const char *ip, uint16_t port);

/**
 * @brief	accept wrap function
 */
int net_accept(int lsfd, struct sockaddr *sa, socklen_t *addrlen);

/**
 * @brief	select wrap function
 */
int net_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeo);

/****************************************************************
 * set/get socket option
 ****************************************************************/

/**
 * @brief	set socket receive buffer size
 */
int net_set_rcvbuf(int fd, void *optval);

/**
 * @brief	get socket receive buffer size
 */
int net_get_rcvbuf(int fd, void *optval);

/**
 * @brief	set socket send buffer size
 */
int net_set_sndbuf(int fd, void *optval);

/**
 * @brief	get socket send buffer size
 */
int net_get_sndbuf(int fd, void *optval);

/**
 * @brief	set socket reuse addr option
 */
int net_set_reuseaddr(int fd, int *optval);

/**
 * @brief	get socket reuse addr option
 */
int net_get_reuseaddr(int fd, int *optval);

/**
 * @brief	set socket keepalive
 */
int net_set_keepalive(int fd, int *optval);

/**
 * @brief	get socket keepalive
 */
int net_get_keepalive(int fd, int *optval);

/**
 * @brief	set socket receive timeout
 */
int net_set_rcvtimeo(int fd, struct timeval *tv);

/**
 * @brief	get socket receive timeout
 */
int net_get_rcvtimeo(int fd, struct timeval *tv);

/**
 * @brief	set socket send timeout
 */
int net_set_sndtimeo(int fd, struct timeval *tv);

/**
 * @brief	get socket send timeout
 */
int net_get_sndtimeo(int fd, struct timeval *tv);

/**
 * @brief	set socket to block
 */
int net_set_blocking(int fd);

/**
 * @brief	set socket to non-block
 */
int net_set_nonblocking(int fd);

/****************************************************************
 * read/write or recv/send function
 ****************************************************************/

/**
 * @brief	read in block mode with timeout
 */
ssize_t net_read_timeo(int fd, void *buf, size_t nbytes, int msec);

/**
 * @brief	write in block mode with timeout
 */
ssize_t net_write_timeo(int fd, void *buf, size_t nbytes, int msec);

/**
 * @brief	read timeout
 */
ssize_t net_read_ms(int fd, void *buf, size_t nbytes, int msec);

/**
 * @brief	read timeout
 */
ssize_t net_read_tv(int fd, void *buf, size_t nbytes, struct timeval *tv);

/**
 * @brief	recv timeout
 */
ssize_t net_recv_ms(int fd, void *buf, size_t nbytes, int msec);

/**
 * @brief	recv timeout
 */
ssize_t net_recv_tv(int fd, void *buf, size_t nbytes, struct timeval *tv);

/**
 * @brief	write timeout
 */
ssize_t net_write_ms(int fd, void *buf, size_t nbytes, int msec);

/**
 * @brief	write timeout
 */
ssize_t net_write_tv(int fd, void *buf, size_t nbytes, struct timeval *tv);

/**
 * @brief	send timeout
 */
ssize_t net_send_ms(int fd, void *buf, size_t nbytes, int msec);

/**
 * @brief	send timeout
 */
ssize_t net_send_tv(int fd, void *buf, size_t nbytes, struct timeval *tv);

#endif /*_NET_H_*/
